<template>
  <view class="page">
    <view class="search">
      <view class="search-content">
        <input
          class="search-input"
          placeholder="买券包下单更优惠哦"
          v-model="keyword"
          :focus="!showSearchResultListArea"
          @focus="isInputFocused = !(showSearchResultListArea = false)"
          @blur="isInputFocused = false"
          confirm-type="search"
          @confirm="search()"
        />
        <view class="search-button" @click="search()">
          <span class="search-text" v-if="isInputFocused">搜索</span>
        </view>
      </view>
      <view class="search-switching" v-if="!isInputFocused">
        <span class="switching-search-type" @click="changeSearchMode()"
          >切到<br />{{ isSearchProduct ? '店铺' : '商品' }}</span
        >
        <span>|</span>
        <span class="switching-search-area" @click="$store.user.positionStore.globalLocation.requestLocationForManual()"
          >切换<br />地址</span
        >
      </view>
    </view>
    <view class="result-area" :style="{ display: showSearchResultListArea ? 'flex' : 'none' }">
      <view class="stickyBox">
        <CheckBox
          :options="shopCheckBoxOperation"
          :mixinOptions="mixinOptions"
          @change="loadData()"
          @ready="showSearchResultListArea && loadData()"
          class="stickyBox"
          ref="checkBoxRef"
        />
      </view>
      <view class="list">
        <scroll-view
          :refresher-enabled="isContainerScrollAllowed"
          @scrolltolower="loadData(true)"
          :scroll-y="isContainerScrollAllowed"
          class="scroll-container"
          :refresher-triggered="isTriggered"
          @refresherrefresh="onRefresherrefresh()"
        >
          <view class="body">
            <view class="stores">
              <template v-if="isSearchProduct">
                <ShopProduct v-for="(item, index) in nearbyShopProductsPageData" :data="item" :key="index" />
              </template>
              <template v-else>
                <Shop v-for="(item, index) in nearbyShopPageData" :data="item" :key="index" />
              </template>
            </view>
            <p class="loading">
              <span v-if="page.total === undefined || page.currentPage < Math.ceil((page.total || 0) / page.pageSize)"
                >正在加载...</span
              >
              <span v-else-if="page.total === 0">没有找到匹配{{ isSearchProduct ? '商品' : '店铺' }}</span>
              <span v-else>没有更多了</span>
            </p>
          </view>
        </scroll-view>
      </view>
    </view>
    <view class="search-history" v-show="!showSearchResultListArea">
      <view class="title-row">
        <span>历史搜索</span>
        <uni-icons type="trash" size="20" color="#BDBDBD" @click="clearSearchHistory"></uni-icons>
      </view>
      <view class="history-keyword-list">
        <span
          class="history-keyword"
          v-for="(historyKeyword, index) in searchHistoryRef"
          :key="index"
          @click="search(historyKeyword)"
          >{{ historyKeyword }}</span
        >
      </view>
    </view>
  </view>
</template>

<script setup lang="ts">
import $store from '@/store'
import { ref } from 'vue'
import shopCheckBoxOperation from '@/common/check-box-operation-store/shopCheckBoxOperation'
import CheckBox from '@/components/check-box/index.vue'
import { Page } from '@/types/generic/Page'
import { type NearbyShop, NearbyShopProduct } from '@/types/response/shop'
import type { MixinSurveyItem, Result } from '@/components/check-box/check-box-selector/type'
import { SearchNearbyShopsPage } from '@/types/param/shop'
import PropertiesCopyUtils from '@/utils/PropertiesCopyUtils'
import $API from '@/api'
import Shop from '@/components/shop/index.vue'
import ShopProduct from '@/components/shop-product/index.vue'

// 接收query
interface Props {
  shopCategoryId?: string
}
const props = withDefaults(defineProps<Props>(), {})

const searchHistoryCachedVariableManager = $store.user.searchHistory
const searchHistoryRef = $store.user.searchHistory.valueRef
const keyword = ref('')
const showSearchResultListArea = ref<boolean>(props.shopCategoryId != null)
const mixinOptions = ref<MixinSurveyItem[]>(
  (props.shopCategoryId && $store.shop.conveyerBelt.takeOut(props.shopCategoryId)) || []
)
const isInputFocused = ref(true)
const isSearchProduct = ref(true) // 产品或商铺
function changeSearchMode() {
  isSearchProduct.value = !isSearchProduct.value
  search()
}
function setPage(data: NearbyShop[], isAppend: boolean, total: number | undefined) {
  if (isAppend) {
    nearbyShopPageData.value.push(...data)
  } else {
    // 重置页数
    nearbyShopPageData.value = data
  }
  page.value.total = total ? parseInt(total + '') : undefined /*undefined表示加载中*/
}
function search(searchKeyword: string = keyword.value) {
  setPage([], false, undefined)
  // historyKeyword -> current input search keyword
  // 记录到搜索历史
  recordSearch(searchKeyword)
  keyword.value = searchKeyword
  // 切换到搜索视图
  showSearchResultListArea.value = true
  // 搜索逻辑 searchHandler
  loadData()
}

// 记录到搜索历史
function recordSearch(keyword: string) {
  if (keyword == null || keyword.trim().length == 0) return
  let historyList = searchHistoryRef.value || []
  // 过滤
  historyList = historyList.filter((item) => item != keyword)
  // 放到头部
  historyList.unshift(keyword)
  // 重新缓存
  searchHistoryCachedVariableManager.setValue(historyList)
}
// 清空搜索历史
function clearSearchHistory() {
  searchHistoryCachedVariableManager.setValue([])
}
// 分页参数
const checkBoxRef = ref()
const globalLocation = ref($store.user.positionStore.globalLocation)
const page = ref<Page & { total?: number }>({ ...new Page(), pageSize: 15 })
const nearbyShopPageData = ref<NearbyShop[]>([])
const nearbyShopProductsPageData = ref<NearbyShopProduct[]>([])
const isContainerScrollAllowed = ref(true)

async function loadData(isAppend = false) {
  async function loadShopData(isAppend = false) {
    // 根据是否追加设置加载的页数
    const result = await $API.shop.searchNearbyShops(buildPageRequestParams(isAppend))
    if (result.success) setPage(result.data.list, isAppend, result.data.total)
  }
  async function loadProductData(isAppend = false) {
    // 根据是否追加设置加载的页数
    const result = await $API.shop.searchNearbyShopProducts(buildPageRequestParams(isAppend))
    if (result.success) {
      // 前面的不要
      if (isAppend) {
        nearbyShopProductsPageData.value.push(...result.data.list)
      } else {
        // 重置页数
        nearbyShopProductsPageData.value = result.data.list
      }
      page.value.total = parseInt(result.data.total + '')
    }
  }
  isSearchProduct.value ? loadProductData(isAppend) : loadShopData(isAppend)
}

function buildPageRequestParams(isAppend = false): SearchNearbyShopsPage {
  const results: Result[] = checkBoxRef.value?.getSubmitData()
  results.push({
    name: 'keyword',
    value: keyword.value
  })
  const searchNearbyShopsPage = new SearchNearbyShopsPage()
  let conditionObj = results?.reduce(
    (acc, currVal: Result) => {
      acc[currVal.name] = currVal.value
      return acc
    },
    {} as { [key: string]: any }
  )
  isAppend ? page.value.currentPage++ : (page.value.currentPage = 1)
  PropertiesCopyUtils.copy(
    [globalLocation.value, globalLocation.value.locationLevelName, conditionObj, page.value],
    searchNearbyShopsPage
  )
  return searchNearbyShopsPage
}

// 下拉刷新状态
const isTriggered = ref(false)
async function onRefresherrefresh() {
  // 开启动画
  isTriggered.value = true
  // 加载下一页追加数据
  page.value.currentPage++
  await Promise.all([loadData()])
  isTriggered.value = false
}
</script>

<style scoped lang="scss">
.page {
  display: flex;
  width: 100vw;
  height: 100vh;
  background-color: #f6f6f6;
  flex-direction: column;

  .search {
    display: flex;
    padding: 8px 30rpx 4px;
    box-sizing: border-box;

    $search-area-height: 84rpx;

    .search-content {
      display: flex;
      align-items: center;
      overflow: hidden;
      height: $search-area-height;
      border-radius: $search-area-height * 0.5;
      background-color: #fff;
      box-sizing: border-box;
      flex-grow: 1;

      .search-input {
        padding: 0 30rpx;
        height: 100%;
        flex-grow: 1;
        box-sizing: border-box;
        font-size: $search-area-height * 0.34;
      }

      .search-button {
        display: flex;
        align-items: center;
        height: 100%;

        .search-text {
          padding: 0 30rpx;
          font-size: 28rpx;
          font-weight: bold;
          border-left: 1px solid #00000050;
          white-space: nowrap;
        }
      }
    }

    .search-switching {
      $switching-item-margin-size: 15rpx;

      display: flex;
      align-items: center;
      font-size: $search-area-height * 0.25;
      transition: all 3s ease; /* 过渡改变宽度 */

      > .switching-search-type {
        margin: 0 $switching-item-margin-size;
      }

      > .switching-search-area {
        margin-left: $switching-item-margin-size;
      }
    }
  }

  .search-history {
    $top-radius-size: 35rpx;
    $padding-size: $top-radius-size * 0.7;

    margin-top: 5px;
    padding: $padding-size $padding-size 0;
    width: 100%;
    background-color: #fff;
    flex-grow: 1;
    border-top-left-radius: $top-radius-size;
    border-top-right-radius: $top-radius-size;
    box-sizing: border-box;

    .title-row {
      display: block;
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding-bottom: 12rpx;
      font-size: 28rpx;
      font-weight: 600;
    }

    .history-keyword-list {
      display: flex;
      width: 100%;
      flex-wrap: wrap;
      box-sizing: border-box;

      .history-keyword {
        $line-height: 48rpx;

        display: inline-block;
        margin: 10rpx 20rpx 10rpx 0;
        padding: 0 $line-height * 0.75;
        font-size: $line-height * 0.55;
        border-radius: $line-height * 0.5;
        color: #000;
        background-color: #f6f6f6;
        line-height: $line-height;
        box-sizing: border-box;
      }
    }
  }

  .result-area {
    // display: flex; 在行内样式中进行条件定义
    width: 100%;
    flex-grow: 1;
    flex-direction: column;

    .stickyBox {
      flex-shrink: 0;

      /* 确保在result list上面 */
      z-index: 1;
    }

    .list {
      flex-grow: 1;

      /* 确保在result list上面 */
      z-index: 0;

      .scroll-container {
        width: 100%;
        height: 100%;

        .body {
          .loading {
            height: 70rpx;
            font-size: 28rpx;
            text-align: center;
            color: #5f6368;
            line-height: 70rpx;
          }
        }
      }
    }
  }
}
</style>
